package com.hjr.leetcode.question100;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * 寻找两个正序数组的中位数
 * 给定两个大小分别为 m 和 n 的正序（从小到大）数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
 * 算法的时间复杂度应该为 O(log (m+n)) 。
 */
public class q4 {

    public static void main(String[] args) throws UnknownHostException {
        double medianSortedArrays = findMedianSortedArrays2(new int[]{1, 2}, new int[]{3,4});
        System.out.println(medianSortedArrays);
    }

    //最简单-归并 1ms 44mb 时间复杂度O(m+n) 空间复杂度O(m+n)
    public static double findMedianSortedArrays1(int[] nums1, int[] nums2) {
        //将两个数组合为一个，查找中位数
        int m = nums1.length;
        int n = nums2.length;
        int[] nums = new int[m + n];

        if (m == 0){
            if (n % 2 == 0) {
                return (nums2[n / 2 - 1] + nums2[n / 2]) / 2.0;
            } else {
                return nums2[n / 2];
            }
        }
        if (n == 0) {
            if (m % 2 == 0) {
                return (nums1[m / 2 - 1] + nums1[m / 2]) / 2.0;
            } else {
                return nums1[m / 2];
            }
        }

        //合并操作 由于两个是有序的，只需要判断两个数组第一个元素即可
        int count = 0;
        int i = 0, j = 0;
        while (count != (m + n)) {
            if (i == m) {
                while (j != n) {
                    nums[count++] = nums2[j++];
                }
                break;
            }
            if (j == n) {
                while (i != m) {
                    nums[count++] = nums1[i++];
                }
                break;
            }

            if (nums1[i] < nums2[j]) {
                nums[count++] = nums1[i++];
            } else {
                nums[count++] = nums2[j++];
            }
        }


        if (count % 2 == 0) {
            return (nums[count / 2 - 1] + nums[count / 2]) / 2.0;
        } else {
            return nums[count / 2];
        }
    }

    //业务归并（不合并数组） 1ms 45mb 时间复杂度O(m+n) 空间复杂度O(1)
    public static double findMedianSortedArrays2(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int len = m + n;
        int left = -1, right = -1;
        int aStart = 0, bStart = 0;
        for (int i = 0; i <= len / 2; i++) {
            left = right;
            if (aStart < m && (bStart >= n || nums1[aStart] < nums2[bStart])) {
                right = nums1[aStart++];
            } else {
                right = nums2[bStart++];
            }
        }
        if ((len & 1) == 0) {
            return (left + right) / 2.0;
        }
        else {
            return right;
        }
    }


    //二分查找-进阶重点 TODO
//    public static double findMedianSortedArraysP(int[] nums1, int[] nums2) {
//
//    }

}
